#pragma once
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include "Log.hpp"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include "Err.hpp"
#include <functional>
#include "Sock.hpp"
#include <pthread.h>
using namespace std;

using func_t = function<string(string &)>;

class Server;//声明一下，在ThreadData中要用到

struct ThreadData
{
    ThreadData(uint16_t clientport, string clientip, Server *ptr, int sock)
        : _clientport(clientport),
          _clientip(clientip),
          _ptr(ptr),
          _sock(sock)
    {
    }
    uint16_t _clientport;
    string _clientip;
    Server *_ptr; // 服务器类的指针
    int _sock;    // accept返回的值，用来通信的
};

class Server
{
public:
    Server(uint16_t port, func_t func)
        : _port(port),
          _func(func)
    {
    }
    void Init() // 通过Sock来把前置网络通信的工作完成,初始化
    {
        _sock.Socket();
        _sock.Bind(_port);
        _sock.Listen();
    }
    void Start()
    {
        while (1)
        {
            string clientip;
            uint16_t clientport;
            int sock = _sock.Accept(clientip, clientport);
            // 用来网络通信的关键，因此命名为sock
            if (sock < 0)
            {
                // 如果接收失败，那就重新接收
                continue;
            }
            pthread_t pid;
            ThreadData *data = new ThreadData(clientport, clientip, this, sock);
            pthread_create(&pid, nullptr, Routine, data);
        }
    }

    void HandlerHttpRequest(ThreadData *data) // 处理接受请求和应答
    {
        LogMessage(Debug,"开始通信");
        while (1)
        {
            char buff[4096]; // 接收的内容
            int n = recv(data->_sock, buff, sizeof(buff) - 1, 0);
            if (n > 0)
            {
                buff[n]=0;
               //LogMessage(Debug,"客户端信息：%s",buff);
                string request(buff);
                string response = _func(request);
                send(data->_sock, response.c_str(), response.size(), 0);
            }
            else if (n == 0)
            {
                //客户端关闭了链接
                cout<<"客户端关闭了链接，服务器也要关闭链接了"<<endl;
                return;
            }
            else // n<0出错
            {
                LogMessage(Error,"recv error");
                continue;
            }
        }
    }

    static void *Routine(void *arg) // 线程所调用的函数
    {
        pthread_detach(pthread_self());
        ThreadData *data = static_cast<ThreadData *>(arg);
        data->_ptr->HandlerHttpRequest(data);
        close(data->_sock);//remember
        delete data;//remember
        return nullptr;
    }

private:
    uint16_t _port;
    Sock _sock;
    func_t _func;
};